package com.p2p.base.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;

public class DateUtil {
	private static final SimpleDateFormat dayFormat = new SimpleDateFormat(
			"yyyy-MM-dd");
	private static final SimpleDateFormat yyyyMMddFormat = new SimpleDateFormat(
			"yyyyMMdd");
	private static final SimpleDateFormat timeFormat = new SimpleDateFormat(
			"HH:mm:ss");
	private static final SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
	private static final SimpleDateFormat minuteFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm");

	public static long buildLastTime(long initTime, long addTime) {
		long nowTime = System.currentTimeMillis();
		if (nowTime < initTime)
			return initTime + addTime;
		return nowTime + addTime;
	}

	public static long getNowTime() {
		return System.currentTimeMillis();
	}

	public static boolean isAlive(long time) {
		return getNowTime() >= time;
	}

	public static Date addDay(Date date, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_YEAR, days);
		return calendar.getTime();
	}

	public static Date addMonth(Date date, int month) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, month);
		return calendar.getTime();
	}

	public static Date getTheDayStartTime(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(11, 0);
		calendar.set(12, 0);
		calendar.set(13, 0);
		calendar.set(14, 0);
		return calendar.getTime();
	}

	public static Date getTheDayEndTime(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(11, 23);
		calendar.set(12, 59);
		calendar.set(13, 59);
		calendar.set(14, 999);
		return calendar.getTime();
	}

	public static long getTheDayEndTime(long date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(date);
		calendar.set(11, 23);
		calendar.set(12, 59);
		calendar.set(13, 59);
		return calendar.getTimeInMillis();
	}

	public static long getTheDayStartTime(long dateTime) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(dateTime);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		return calendar.getTimeInMillis();
	}

	public static int getMillisBetweenTwoDate(long firstTime, long lastTime) {
		return (int) (firstTime - lastTime);
	}

	public static int getMinutesBetweenTwoDate(long firstTime, long lastTime) {
		long millis = getMillisBetweenTwoDate(firstTime, lastTime);
		int minutes = (int) (millis / 60000);
		return minutes;
	}

	public static int getSecondsBetweenTwoDate(long firstTime, long lastTime) {
		long millis = getMillisBetweenTwoDate(firstTime, lastTime);
		int minutes = (int) (millis / 1000);
		return minutes;
	}

	public static int getDayBetweenTwoDate(Date firstTime, Date lastTime)
			throws Exception {
		if ((firstTime == null) || (lastTime == null)) {
			throw new Exception("param can not null");
		}
		return getDayBetweenTwoDate(firstTime.getTime(), lastTime.getTime());
	}

	public static Double getDayBetweenTwoDateDouble(Date firstTime, Date lastTime)
			throws Exception {
		if ((firstTime == null) || (lastTime == null)) {
			throw new Exception("param can not null");
		}
		return getDayBetweenTwoDateDouble(firstTime.getTime(), lastTime.getTime());
	}
	
	public static Double getDayBetweenTwoDateDouble(long firstTime, long lastTime) {
		long firstCalendaStartTime = getTheDayStartTime(firstTime);
		long lastCalendaStartTime = getTheDayStartTime(lastTime);
		Double days = (firstCalendaStartTime - lastCalendaStartTime)*1.00 / 86400000;
		return days;
	}
	
	/**
	 * @param firstTime
	 * @param lastTime
	 * 
	 *            firstTime 大于 lastTime 返回正数
	 * @return
	 */
	public static int getDayBetweenTwoDate(long firstTime, long lastTime) {
		long firstCalendaStartTime = getTheDayStartTime(firstTime);
		long lastCalendaStartTime = getTheDayStartTime(lastTime);
		Long days = new Long(
				(firstCalendaStartTime - lastCalendaStartTime) / 86400000l);

		return days.intValue();
	}

	
	public static int getMinutesBetweenTwoDate(Date firstTime, Date lastTime)
			throws Exception {
		if ((firstTime == null) || (lastTime == null)) {
			throw new Exception("param can not null");
		}
		return getMinutesBetweenTwoDate(firstTime.getTime(), lastTime.getTime());
	}

	public static int getSecondsBetweenTwoDate(Date firstTime, Date lastTime)
			throws Exception {
		if ((firstTime == null) || (lastTime == null)) {
			throw new Exception("param can not null");
		}
		return getSecondsBetweenTwoDate(firstTime.getTime(), lastTime.getTime());
	}

	public static int getMillisBetweenTwoDate(Date firstTime, Date lastTime)
			throws Exception {
		if ((firstTime == null) || (lastTime == null)) {
			throw new Exception("param can not null");
		}
		return getMillisBetweenTwoDate(firstTime.getTime(), lastTime.getTime());
	}

	public static boolean isSameDay(Date date1, Date date2) {
		String strDate1 = getDateStr(date1);
		String strDate2 = getDateStr(date2);

		if (StringUtils.equals(strDate1, strDate2)) {
			return true;
		}
		return false;
	}

	public static boolean isSameDay(long time1, long time2) {
		return isSameDay(new Date(time1), new Date(time2));
	}

	public static String getDateStr(Object date) {
		synchronized (dayFormat) {
			String strDate = dayFormat.format(date);
			return strDate;
		}
	}

	public static String getTimeStr(Object date) {
		synchronized (timeFormat) {
			String strDate = timeFormat.format(date);
			return strDate;
		}
	}

	public static String getDateTime(Object date) {
		synchronized (dateTimeFormat) {
			String strDate = dateTimeFormat.format(date);
			return strDate;
		}
	}

	public static String getYYYYMMDDHHMMStr(Object date) {
		synchronized (minuteFormat) {
			String strDate = minuteFormat.format(date);
			return strDate;
		}
	}

	public static String getYYYYMMDDStr(Object date) {
		synchronized (yyyyMMddFormat) {
			String strDate = yyyyMMddFormat.format(date);
			return strDate;
		}
	}

	public static Date parseYYYYMMDDStr(String String) throws ParseException {
		synchronized (yyyyMMddFormat) {
			Date date = yyyyMMddFormat.parse(String);
			return date;
		}
	}

	public static Date parseStandardDate(String str) throws ParseException {
		synchronized (dayFormat) {
			Date date = dayFormat.parse(str);
			return date;
		}
	}

	public static Date parseDateTime(String str) throws ParseException {
		synchronized (dateTimeFormat) {
			Date date = dateTimeFormat.parse(str);
			return date;
		}
	}

	public static void main(String[] args) {

		Date now = new Date();
		Date d2 = DateUtil.addMonth(now, 1);
		System.out.println(now.toString());
		System.out.println(d2.toString());
		int days = DateUtil.getDayBetweenTwoDate(now.getTime(), d2.getTime());
		System.out.println(days);
	}
}
